//===----------------------------------------------------------------------===//
// Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//===----------------------------------------------------------------------===//

/// Basic mathematical constants and functions.
///
/// Note that some mathematical functions, such as `sign()`, `abs()`, and `round()`,
/// are directly defined in classes [Number], [Int], and [Float].
@ModuleInfo { minPklVersion = "0.31.0" }
module pkl.math

/// The minimum [Int] value: `-9223372036854775808`.
external minInt: Int

/// The minimum [Int8] value: -128.
external minInt8: Int8

/// The minimum [Int16] value: -32768.
external minInt16: Int16

/// The minimum [Int32] value: -2147483648.
external minInt32: Int32

/// The maximum [Int] value: `9223372036854775807`.
external maxInt: Int

/// The maximum [Int8] value: 127.
external maxInt8: Int8

/// The maximum [Int16] value: 32767.
external maxInt16: Int16

/// The maximum [Int32] value: 2147483647.
external maxInt32: Int32

/// The maximum [UInt] value: 9223372036854775807.
///
/// Note that [maxUInt] is equal to [maxInt],
/// not `maxInt * 2 + 1` as one might expect.
/// That is, [UInt] has half the range of [Int].
external maxUInt: UInt

/// The maximum [UInt8] value: 255.
external maxUInt8: UInt8

/// The maximum [UInt16] value: 65535.
external maxUInt16: UInt16

/// The maximum [UInt32] value: 4294967295.
external maxUInt32: UInt32

/// The minimum finite [Float] value: `-1.7976931348623157e308`.
///
/// Operations whose value is less than [minFiniteFloat] return -[infinity].
external minFiniteFloat: Float

/// The maximum finite [Float] value: `1.7976931348623157e308`.
///
/// Operations whose value is greater than [maxFiniteFloat] return [infinity].
external maxFiniteFloat: Float

/// The minimum positive [Float] value that is greater than zero: `4.9e-324`.
external minPositiveFloat: Float

/// The number [e][1].
///
/// [1]: https://en.wikipedia.org/wiki/E_(mathematical_constant)
external e: Float

/// The number [π][1].
///
/// [1]: https://en.wikipedia.org/wiki/Pi
external pi: Float

/// Returns e raised to the power of [exponent].
///
/// [1]: https://en.wikipedia.org/wiki/Exponential_function
external function exp(exponent: Number): Float

/// Returns the [square root][1] of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Square_root
external function sqrt(x: Number): Float

/// Returns the [cube root][1] of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Cube_root
external function cbrt(x: Number): Float

/// Returns the [natural logarithm][1] (base e logarithm) of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Natural_logarithm
external function log(x: Number): Float

/// Returns the [base 2 logarithm][1] of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Binary_logarithm
external function log2(x: Number): Float

/// Returns the [base 10 logarithm][1] of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Common_logarithm
external function log10(x: Number): Float

/// Returns the [sine][1] of [angle] given in radians.
///
/// [1]: https://en.wikipedia.org/wiki/Sine
external function sin(angle: Number): Float

/// Returns the [cosine][1] of [angle] given in radians.
///
/// [1]: https://en.wikipedia.org/wiki/Trigonometric_functions///cosine
external function cos(angle: Number): Float

/// Returns the [tangent][1] of [angle] given in radians.
///
/// [1]: https://en.wikipedia.org/wiki/Tangent
external function tan(angle: Number): Float

/// Returns the [arcsine][1] of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
external function asin(x: Number): Float

/// Returns the [arccosine][1] of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
external function acos(x: Number): Float

/// Returns the [arctangent][1] of [x].
///
/// [1]: https://en.wikipedia.org/wiki/Inverse_trigonometric_functions
external function atan(x: Number): Float

/// Returns the [2-argument arctangent][1] of [x] and [y].
///
/// [1]: https://en.wikipedia.org/wiki/Atan2
@Since { version = "0.28.0" }
external function atan2(x: Number, y: Number): Float

/// Returns the [greatest common divisor][1] of [x] and [y].
///
/// [1]: https://en.wikipedia.org/wiki/Greatest_common_divisor
external function gcd(x: Int, y: Int): Int

/// Returns the [least common multiple][1] of [x] and [y].
///
/// [1]: https://en.wikipedia.org/wiki/Least_common_multiple
external function lcm(x: Int, y: Int): Int

/// Returns `true` if [x] is a power of two.
external function isPowerOfTwo(x: Number): Boolean

/// Returns the minimum of [x] and [y].
external function min(x: Number, y: Number): Number

/// Returns the maximum of [x] and [y].
external function max(x: Number, y: Number): Number
